package com.crazydream.wechat.common.dao.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.crazydream.wechat.common.Constants;
import com.crazydream.wechat.common.dao.BaseDAO;

/**
 * 
 * @author zhouyun
 * 
 */
@Repository("dao")
public class BaseDAOImpl implements BaseDAO{
	
	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;
	
	private Session getSession(){
		return sessionFactory.getCurrentSession();
	}

	/**
	 * 创建对象
	 * @param <T>
	 * @param t
	 * @return
	 */
	public <T> T create(T t) {
		getSession().persist(t);
		getSession().flush();
		getSession().refresh(t);
		return t;
	}

	/**
	 * 根据主键查询
	 * @param <T>
	 * @param <PK>
	 * @param type
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T, PK extends Serializable> T find(Class<T> type, PK id) {
		return (T) getSession().get(type, id);
	}

	/**
	 * 更新对象
	 * @param <T>
	 * @param type
	 * @return
	 */
	public <T> T update(T type) {
		getSession().merge(type);
		return type;
	}

	/**
	 * 根据主键删除对象
	 * @param <T>
	 * @param <PK>
	 * @param type
	 * @param id
	 */
	public <T, PK extends Serializable> void delete(Class<T> type, PK id) {
		@SuppressWarnings("unchecked")
		T ref = (T) getSession().get(type, id);
		getSession().delete(ref);
	}

	/**
	 * SQL查询
	 * @param <T>
	 * @param queryName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findWithNamedQuery(String queryName) {
		return getSession().getNamedQuery(queryName).list();
	}

	
	/**
	 * 查询记录总数
	 */
	public Integer findRowCount(String queryName, Map<String, Object> params) {
		Query query = getSession().createSQLQuery(queryName);
		if(null!=params){
			Set<Entry<String, Object>> rawParameters = params.entrySet();
			for (Entry<String, Object> entry : rawParameters) {
				if(!entry.getKey().equals(Constants.PAGE_CURRENT)&&!entry.getKey().equals(Constants.PAGE_SHOW)){
					query.setParameter(entry.getKey(), entry.getValue());
				}
			}
		}
		return Integer.parseInt(query.list().get(0).toString());
	}

	/**
	 * 带参数的SQL查询
	 * @param <T>
	 * @param queryName
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findWithNamedQuery(String queryName,
			Map<String, Object> params) {
		Query query = getSession().getNamedQuery(queryName);
		if(null!=params){
			Set<Entry<String, Object>> rawParameters = params.entrySet();
			for (Entry<String, Object> entry : rawParameters) {
				query.setParameter(entry.getKey(), entry.getValue());
	
			}
		}
		return query.list();
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findWithSQLQuery(String queryName, Map<String, Object> params){
		Query query = getSession().createSQLQuery(queryName).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		if(null!=params){
			Set<Entry<String, Object>> rawParameters = params.entrySet();
			for (Entry<String, Object> entry : rawParameters) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		return query.list();
	}

	/**
	 * 查询单位对象
	 * @param <T>
	 * @param queryName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T findUniqueWithNamedQuery(String queryName) {
		return (T) getSession().getNamedQuery(queryName).uniqueResult();
	}

	/**
	 * 查询单个对象(带参数)
	 * @param <T>
	 * @param queryName
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T findUniqueWithNamedQuery(String queryName,
			Map<String, Object> params) {
		Set<Entry<String, Object>> rawParameters = params.entrySet();
		Query query = getSession().getNamedQuery(queryName);

		for (Entry<String, Object> entry : rawParameters) {
			query.setParameter(entry.getKey(), entry.getValue());

		}
		return (T) query.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> findList(String queryName, Map<String, Object> params) {
		Query query = getSession().createQuery(queryName);
		if(null!=params){
			Set<Entry<String, Object>> rawParameters = params.entrySet();
			for (Entry<String, Object> entry : rawParameters) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		return query.list();
	}
	
}
